﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using SharpBolt.BasicIntefaces;

namespace SharpBolt.Time
{ 
    public class Timer : IDropable
        {
            public bool IsEnded { get; private set; }
            public double Interval { get; set; }

            double currentTime;
            public double CurrentTime
            {
                get
                {
                    return currentTime;
                }
                set
                {
                    currentTime = value;
                    if (!IsEnded && !Freeze)
                    {

                        if (currentTime >= Interval)
                        {
                            currentTime = Interval;
                            IsEnded = true;
                            if (Ended != null) Ended(this, EventArgs.Empty);
                        }
                    }
                }
            }
            public double CurrentPart
            {
                get
                {
                    return Math.Max(0, Math.Min(1, ((double)CurrentTime) / Interval));
                }
                set
                {
                    CurrentTime = (Math.Max(0, Math.Min(1, value) * Interval));
                }
            }

            public bool Freeze;

            public void Start(double interval)
            {
                Interval = interval;
                ReStart();
            }
            public void ReStart()
            {
                Freeze = false;
                IsEnded = false;
                currentTime = 0;
            }

            public event EventHandler Ended;

            internal TimeManager manager;

            internal Timer()
            {

            }

            public bool IsDropped { get; set; }

            public void Drop()
            {
                Ended = null;
                manager.DropTimer(this);
            }
        }

    public class TimeManager
    {
       

        List<Timer> Timers { get; set; }

        public bool IsFrozen { get; set; }

        public double Now //Milliseconds
        {
            get
            {
                if (IsFrozen)
                {
                    return lastTime;
                }
                else
                {
                    return Engine.Miscs.GetMilliseconds();
                }
            }
        }

        public TimeManager()
        {
            Timers = new List<Timer>();
            lastTime = Engine.Miscs.GetMilliseconds();
            RelativeSpeed = 1;
        }

        public Timer CreateTimer()
        {
            Timer timer = new Timer();
            timer.IsDropped = false;
            timer.Freeze = true;
            timer.manager = this;
            Timers.Add(timer);
            return timer;
        }

        public void DropTimer(Timer timer)
        {            
            timer.IsDropped = true;
        }

        long minFPS = 30;
        double delta;

        public double RelativeSpeed{get;set;}

        public double Delta
        {
            get
            {
                if (IsFrozen)
                    return 0;
                else
                    return delta;
            }
            private set
            {
                delta = value;
                if (delta > 1000 / minFPS)
                    delta = 1000 / minFPS;
            }
        }
        public double DeltaSecond { get { return Delta / 1000.0; } }

        double lastTime;

        public void Update()
        {
            if (IsFrozen) return;

            double currentTime = Now;
            Delta = (currentTime - lastTime) * RelativeSpeed;
            lastTime = currentTime;

            foreach (var timer in Timers)
            {
                if (!timer.Freeze)
                {
                    timer.CurrentTime += Delta;
                }
            }

            Timers.RemoveAll(p=>p.IsDropped);
        }
    }
}
